package com.ruoyi.mp.service.impl;

import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.db.domain.system.*;
import com.ruoyi.db.domain.web.MpIncomeRecord;
import com.ruoyi.db.mapper.system.*;
import com.ruoyi.db.mapper.web.MpIncomeRecordMapper;
import com.ruoyi.mp.controller.PcRaiseController;
import com.ruoyi.mp.service.IMpClientRaiseRecordService;
import com.ruoyi.mp.service.IPcRaiseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户参与众筹活动记录Service业务层处理
 * 
 * @author ruoyi
 * @date 2022-08-03
 */
@Service
@Transactional(rollbackOn = Exception.class)
public class MpClientRaiseRecordServiceImpl implements IMpClientRaiseRecordService
{
    @Autowired
    private MpClientRaiseRecordMapper mpClientRaiseRecordMapper;
    @Autowired
    private PcRaiseMapper pcRaiseMapper;
    @Autowired
    private MpClientMapper mpClientMapper;
    @Autowired
    private MpIncomeRecordMapper mpIncomeRecordMapper;
    @Autowired
    private PcRaiseSystemConfigMapper pcRaiseSystemConfigMapper;
    @Autowired
    private MpClientCardMapper mpClientCardMapper;
    @Autowired
    private PcCardMapper pcCardMapper;
    @Autowired
    private IPcRaiseService pcRaiseService;

    /**
     * 查询用户参与众筹活动记录
     * 
     * @param id 用户参与众筹活动记录主键
     * @return 用户参与众筹活动记录
     */
    @Override
    public MpClientRaiseRecord selectMpClientRaiseRecordById(Long id)
    {
        return mpClientRaiseRecordMapper.selectMpClientRaiseRecordById(id);
    }

    /**
     * 查询用户参与众筹活动记录列表
     * 
     * @param mpClientRaiseRecord 用户参与众筹活动记录
     * @return 用户参与众筹活动记录
     */
    @Override
    public List<MpClientRaiseRecord> selectMpClientRaiseRecordList(MpClientRaiseRecord mpClientRaiseRecord)
    {
        if(mpClientRaiseRecord.getTakeType()==1){
            List<MpClientRaiseRecord> list =  mpClientRaiseRecordMapper.selectMpClientRaiseRecordListMyTake(mpClientRaiseRecord);
            if(list!=null&&list.size()!=0){
                for (MpClientRaiseRecord raiseRecord:list) {
                    PcRaise raise = pcRaiseMapper.selectPcRaiseById(raiseRecord.getRaiseId());
                    raiseRecord.setRaiseName(raise.getRaiseName());
                    raiseRecord.setListTime(raise.getListCount());
                    raiseRecord.setRaiseRate(raise.getEarnRate());
                    raiseRecord.setStartTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",raise.getStartTime()));
                    raiseRecord.setTotalAmount(raise.getTotalAmount());
                    raiseRecord.setTakeTime(raiseRecord.getOrderTime());
                    if(raiseRecord.getCardId()!=null&&raiseRecord.getCardId()!=0){
                        PcCard card = pcCardMapper.selectPcCardById(raiseRecord.getCardId());
                        if(card!=null){
                            raiseRecord.setCardName(card.getName());
                        }
                    }
                    if(raise.getIsAble()==1&&raise.getIsOver()==0){
                        raiseRecord.setRaiseStatus("1");
                    }
                    if(raise.getIsSuccess()==1){
                        raiseRecord.setRaiseStatus("2");
                    }
                    if(raise.getIsSuccess()==0&&raise.getIsAble()==1&&raise.getIsOver()==1){
                        raiseRecord.setRaiseStatus("3");
                    }
                    if(raiseRecord.getIsRaiseAble()==0){
                        raiseRecord.setRaiseStatus("4");
                    }
                }
            }
            return list;
        }
        if(mpClientRaiseRecord.getTakeType()==2){
            List<MpClientRaiseRecord> list = mpClientRaiseRecordMapper.selectMpClientRaiseRecordListMyOrder(mpClientRaiseRecord);
            if(list!=null&&list.size()!=0){
                for (MpClientRaiseRecord raiseRecord:list) {
                    PcRaise raise = pcRaiseMapper.selectPcRaiseById(raiseRecord.getRaiseId());
                    raiseRecord.setRaiseName(raise.getRaiseName());
                    raiseRecord.setListTime(raise.getListCount());
                    raiseRecord.setRaiseRate(raise.getEarnRate());
                    raiseRecord.setStartTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",raise.getStartTime()));
                    raiseRecord.setTotalAmount(raise.getTotalAmount());

                    if(raiseRecord.getCardId()!=null&&raiseRecord.getCardId()!=0){
                        PcCard card = pcCardMapper.selectPcCardById(raiseRecord.getCardId());
                        if(card!=null){
                            raiseRecord.setCardName(card.getName());
                        }
                    }
                    if(raise.getIsAble()==1&&raise.getIsOver()==0){
                        raiseRecord.setRaiseStatus("1");
                    }
                    if(raise.getIsSuccess()==1){
                        raiseRecord.setRaiseStatus("2");
                    }
                    if(raise.getIsSuccess()==0&&raise.getIsAble()==1&&raise.getIsOver()==1){
                        raiseRecord.setRaiseStatus("3");
                    }
                    if(raiseRecord.getIsRaiseAble()==0){
                        raiseRecord.setRaiseStatus("4");
                    }
                }
            }
            return list;
        }
        return null;
    }

    /**
     * 新增用户参与众筹活动记录
     * 
     * @param mpClientRaiseRecord 用户参与众筹活动记录
     * @return 结果
     */
    @Override
    public int insertMpClientRaiseRecord(MpClientRaiseRecord mpClientRaiseRecord)
    {
        return mpClientRaiseRecordMapper.insertMpClientRaiseRecord(mpClientRaiseRecord);
    }

    /**
     * 修改用户参与众筹活动记录
     * 
     * @param mpClientRaiseRecord 用户参与众筹活动记录
     * @return 结果
     */
    @Override
    public int updateMpClientRaiseRecord(MpClientRaiseRecord mpClientRaiseRecord)
    {
        return mpClientRaiseRecordMapper.updateMpClientRaiseRecord(mpClientRaiseRecord);
    }

    /**
     * 批量删除用户参与众筹活动记录
     * 
     * @param ids 需要删除的用户参与众筹活动记录主键
     * @return 结果
     */
    @Override
    public int deleteMpClientRaiseRecordByIds(Long[] ids)
    {
        return mpClientRaiseRecordMapper.deleteMpClientRaiseRecordByIds(ids);
    }

    /**
     * 删除用户参与众筹活动记录信息
     * 
     * @param id 用户参与众筹活动记录主键
     * @return 结果
     */
    @Override
    public int deleteMpClientRaiseRecordById(Long id)
    {
        return mpClientRaiseRecordMapper.deleteMpClientRaiseRecordById(id);
    }

    @Override
    public synchronized void orderRecord(MpClientRaiseRecord mpClientRaiseRecord, MpClient client) {
        //修改用户道具卡数量
        if(mpClientRaiseRecord.getCardId()!=null&&mpClientRaiseRecord.getCardId()!=0){
            MpClientCard mpClientCard = new MpClientCard();
            mpClientCard.setCardId(mpClientRaiseRecord.getCardId());
            mpClientCard.setClientId(client.getClientId());
            List<MpClientCard> list =mpClientCardMapper.selectMpClientCardList(mpClientCard);
            if(list==null||list.size()==0){
                return;
            }
            MpClientCard mpClientCard1 = list.get(0);
            if(mpClientCard1.getCardCount()<=0){
                throw new ServiceException("用户道具卡数量不足");
            }
            mpClientCard1.setCardCount(mpClientCard1.getCardCount()-1);
            mpClientCardMapper.updateMpClientCard(mpClientCard1);
        }
        mpClientRaiseRecord.setTakeType(1);
        //如果是优先预购,则扣除用户银藻
        Date now = new Date();
        mpClientRaiseRecord.setTakeTime(now);
        PcRaise raise = pcRaiseMapper.selectPcRaiseById(mpClientRaiseRecord.getRaiseId());
        if(mpClientRaiseRecord.getIsFirstOrder()!=null&&mpClientRaiseRecord.getIsFirstOrder()==1){
            if(!(now.after(raise.getOrderTime())&&now.before(raise.getFirstOrderTime()))){
                throw new ServiceException("不在优先预约时间内");
            }
            PcRaiseSystemConfig pcRaiseSystemConfig = new PcRaiseSystemConfig();
            List<PcRaiseSystemConfig> configs = pcRaiseSystemConfigMapper.selectPcRaiseSystemConfigList(pcRaiseSystemConfig);
            BigDecimal rate = configs.get(0).getFirstOrderSilverRate();
            BigDecimal silver = raise.getTotalAmount().multiply(rate).setScale( 2, BigDecimal.ROUND_HALF_UP );
            if(client.getSilverBeanBalance().compareTo(silver)<0){
                throw new ServiceException("用户银藻余额不足");
            }
            client.setSilverBeanBalance(client.getSilverBeanBalance().subtract(silver));
            mpClientMapper.updateMpClient(client);
            //增加用户银藻收益记录
            MpIncomeRecord mpIncomeRecord = new MpIncomeRecord();
            mpIncomeRecord.setIsIncome(0l);
            mpIncomeRecord.setType(2l);
            mpIncomeRecord.setCreateTime(now);
            mpIncomeRecord.setClientId(client.getClientId());
            mpIncomeRecord.setContent("优先预购扣除银藻");
            mpIncomeRecord.setAmount(silver);
            mpIncomeRecord.setCurrentBalance(client.getSilverBeanBalance());
            mpIncomeRecordMapper.insertMpIncomeRecord(mpIncomeRecord);
            mpClientRaiseRecord.setFirstOrderSilverAmount(silver);
        }else{
            Date orderTime =raise.getOrderTime();
            if(!(now.after(orderTime)&&now.before(raise.getStartTime()))){
                throw new ServiceException("不在预约时间内");
            }
        }
        mpClientRaiseRecord.setOrderTime(now);
        mpClientRaiseRecord.setGetGoldAmount(new BigDecimal(0));
        mpClientRaiseRecord.setGetSilverAmount(new BigDecimal(0));
        mpClientRaiseRecord.setTakeAmount(mpClientRaiseRecord.getOrderAmount());
        if(client.getIsVirtual()==null||client.getIsVirtual()!=1){
            Long carId = mpClientRaiseRecord.getCardId();
            BigDecimal myTake = mpClientRaiseRecord.getOrderAmount();
            BigDecimal limitMin = raise.getMinTakeAmount();
            BigDecimal limitMax = raise.getMaxTakeAmount();
            if(carId!=null&&carId!=0){
                PcCard card = pcCardMapper.selectPcCardById(carId);
                limitMin = limitMin.multiply(card.getAddRate()).setScale( 2, BigDecimal.ROUND_HALF_UP );
                limitMax = limitMax.multiply(card.getAddRate()).setScale( 2, BigDecimal.ROUND_HALF_UP );
            }
            if(myTake.compareTo(new BigDecimal(0))<0){
                throw new ServiceException("不能少于最小参与金额");
            }
            if(myTake.compareTo(limitMax)>0){
                throw new ServiceException("不能超过最大参与金额");
            }
        }
        MpClientRaiseRecord old = new MpClientRaiseRecord();
        old.setClientId(client.getClientId());
        old.setRaiseId(mpClientRaiseRecord.getRaiseId());
        old.setTakeType(1);
        List<MpClientRaiseRecord> oldList = mpClientRaiseRecordMapper.selectMpClientRaiseRecordList(old);
        if(client.getIsVirtual()==null||client.getIsVirtual()!=1) {
            if (oldList.size() > 0) {
                throw new ServiceException("不能重复预约");
            }
        }
        MpClientRaiseRecord oldRaise = new MpClientRaiseRecord();
        oldRaise.setRaiseId(mpClientRaiseRecord.getRaiseId());
        List<MpClientRaiseRecord> oldRaiseList = mpClientRaiseRecordMapper.selectMpClientRaiseRecordList(oldRaise);
        BigDecimal orderSum = oldRaiseList.stream().map( MpClientRaiseRecord:: getOrderAmount).reduce(BigDecimal.ZERO, BigDecimal::add); //BigDecimal类型
        BigDecimal orderTotalSum = raise.getTotalAmount().multiply(new BigDecimal("0.7")).setScale( 0, BigDecimal.ROUND_UP );
        if(orderSum.add(mpClientRaiseRecord.getOrderAmount()).compareTo(orderTotalSum)>0){
            throw new ServiceException("超过可预约金额总和");
        }
        if(client.getGoldBeanBalance()==null||client.getGoldBeanBalance().compareTo(mpClientRaiseRecord.getOrderAmount())<0){
            throw new ServiceException("用户可用金藻不足");
        }
        mpClientRaiseRecord.setIsSettleEarns(0);
        mpClientRaiseRecord.setIsRaiseAble(1);
        mpClientRaiseRecordMapper.insertMpClientRaiseRecord(mpClientRaiseRecord);
        client.setGoldBeanBalance(client.getGoldBeanBalance().subtract(mpClientRaiseRecord.getOrderAmount()));
        mpClientMapper.updateMpClient(client);

        //增加用户银藻收益记录
        MpIncomeRecord mpIncomeRecord = new MpIncomeRecord();
        mpIncomeRecord.setIsIncome(0l);
        mpIncomeRecord.setType(1l);
        mpIncomeRecord.setCreateTime(new Date());
        mpIncomeRecord.setClientId(client.getClientId());
        mpIncomeRecord.setContent("参与预购扣除金藻");
        mpIncomeRecord.setAmount(mpClientRaiseRecord.getOrderAmount());
        mpIncomeRecord.setCurrentBalance(client.getGoldBeanBalance());
        mpIncomeRecordMapper.insertMpIncomeRecord(mpIncomeRecord);


    }

    public static Date addDateTime(Date date, int minute) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MINUTE, minute);// 24小时制 ,加小时
        date = cal.getTime();
        System.out.println(format.format(date));
        return  date;
    }
    class RemindTask extends TimerTask {

        public void run() {
            System.out.println("开始活动结算任务localDateTime:"+new Date());
            //结算时间结算收益
            pcRaiseService.settleByOverTime();;
        }
    }
    @Override
    public synchronized void nowRecord(MpClientRaiseRecord mpClientRaiseRecord, MpClient client) {
        //修改用户道具卡数量
        if(mpClientRaiseRecord.getCardId()!=null&&mpClientRaiseRecord.getCardId()!=0){
            MpClientCard mpClientCard = new MpClientCard();
            mpClientCard.setCardId(mpClientRaiseRecord.getCardId());
            mpClientCard.setClientId(client.getClientId());
            List<MpClientCard> list =mpClientCardMapper.selectMpClientCardList(mpClientCard);
            if(list==null||list.size()==0){
                return;
            }
            MpClientCard mpClientCard1 = list.get(0);
            if(mpClientCard1.getCardCount()<=0){
                throw new ServiceException("用户道具卡数量不足");
            }
            mpClientCard1.setCardCount(mpClientCard1.getCardCount()-1);
            mpClientCardMapper.updateMpClientCard(mpClientCard1);
        }
        mpClientRaiseRecord.setTakeType(2);
        Date now = new Date();
        mpClientRaiseRecord.setTakeTime(now);
        PcRaise raise = pcRaiseMapper.selectPcRaiseById(mpClientRaiseRecord.getRaiseId());
        Date takeEndTime =raise.getContinueTime();
        Date startTime = raise.getStartTime();
        if(!now.after(startTime)){
            throw new ServiceException("活动未开始");
        }
        if(!now.before(takeEndTime)){
            throw new ServiceException("活动时间已截至");
        }
        if(client.getIsVirtual()==null||client.getIsVirtual()!=1){
            Long carId = mpClientRaiseRecord.getCardId();
            BigDecimal myTake = mpClientRaiseRecord.getNowAmount();
            BigDecimal limitMin = raise.getMinTakeAmount();
            BigDecimal limitMax = raise.getMaxTakeAmount();
            if(carId!=null&&carId!=0){
                PcCard card = pcCardMapper.selectPcCardById(carId);
                limitMin = limitMin.multiply(card.getAddRate()).setScale( 2, BigDecimal.ROUND_HALF_UP );
                limitMax = limitMax.multiply(card.getAddRate()).setScale( 2, BigDecimal.ROUND_HALF_UP );
            }
            if(myTake.compareTo(new BigDecimal(1))<0){
                throw new ServiceException("不能少于最小参与金额");
            }
            if(myTake.compareTo(limitMax)>0){
                throw new ServiceException("不能超过最大参与金额");
            }
        }

        MpClientRaiseRecord oldRaise = new MpClientRaiseRecord();
        oldRaise.setRaiseId(mpClientRaiseRecord.getRaiseId());
        List<MpClientRaiseRecord> oldRaiseList = mpClientRaiseRecordMapper.selectMpClientRaiseRecordList(oldRaise);
        BigDecimal takeSum = oldRaiseList.stream().map( MpClientRaiseRecord:: getTakeAmount).reduce(BigDecimal.ZERO, BigDecimal::add); //BigDecimal类型
        BigDecimal takeTotalSum = raise.getTotalAmount();
        if(takeSum.add(mpClientRaiseRecord.getNowAmount()).compareTo(takeTotalSum)>0){
            throw new ServiceException("超过活动金额总和");
        }
        if(client.getGoldBeanBalance()==null||client.getGoldBeanBalance().compareTo(mpClientRaiseRecord.getNowAmount())<0){
            throw new ServiceException("用户可用金藻不足");
        }

        MpClientRaiseRecord old = new MpClientRaiseRecord();
        old.setClientId(client.getClientId());
        old.setRaiseId(mpClientRaiseRecord.getRaiseId());
        old.setTakeType(2);
        List<MpClientRaiseRecord> oldList = mpClientRaiseRecordMapper.selectMpClientRaiseRecordList(old);
        if(oldList.size()>0){
            if(client.getIsVirtual()==null||client.getIsVirtual()!=1){
                throw new ServiceException("已经参与过活动");
            }
        }else{
            mpClientRaiseRecord.setIsSettleEarns(0);
            mpClientRaiseRecord.setIsRaiseAble(1);
            mpClientRaiseRecord.setGetGoldAmount(new BigDecimal(0));
            mpClientRaiseRecord.setGetSilverAmount(new BigDecimal(0));
            mpClientRaiseRecord.setTakeAmount(mpClientRaiseRecord.getNowAmount());
            mpClientRaiseRecord.setFirstOrderSilverAmount(new BigDecimal(0));
            mpClientRaiseRecord.setReturnGoldAmount(new BigDecimal(0));
            mpClientRaiseRecord.setReturnSilverAmount(new BigDecimal(0));
            mpClientRaiseRecordMapper.insertMpClientRaiseRecord(mpClientRaiseRecord);
        }
        client.setGoldBeanBalance(client.getGoldBeanBalance().subtract(mpClientRaiseRecord.getNowAmount()));
        mpClientMapper.updateMpClient(client);

        //增加用户银藻收益记录
        MpIncomeRecord mpIncomeRecord = new MpIncomeRecord();
        mpIncomeRecord.setIsIncome(0l);
        mpIncomeRecord.setType(1l);
        mpIncomeRecord.setCreateTime(new Date());
        mpIncomeRecord.setClientId(client.getClientId());
        mpIncomeRecord.setContent("参与活动扣除金藻");
        mpIncomeRecord.setAmount(mpClientRaiseRecord.getNowAmount());
        mpIncomeRecord.setCurrentBalance(client.getGoldBeanBalance());
        mpIncomeRecordMapper.insertMpIncomeRecord(mpIncomeRecord);

        //获取参与该期活动用户,判断是否众筹成功
//        MpClientRaiseRecord mpClientRaiseRecordR = new MpClientRaiseRecord();
//        mpClientRaiseRecordR.setRaiseId(raise.getId());
//        List<MpClientRaiseRecord> mpClientRaiseRecords =
//                mpClientRaiseRecordMapper.selectMpClientRaiseRecordList(mpClientRaiseRecordR);
//        //获取用户参与的总金额(包括预购和现购)
//        BigDecimal takeSum1 = mpClientRaiseRecords.stream().map( MpClientRaiseRecord:: getTakeAmount).reduce(BigDecimal.ZERO, BigDecimal::add); //BigDecimal类型
//
//        if(raise.getTotalAmount().compareTo(takeSum1)>0){
//
//        }else {
//            Date nows = new Date();
//            Date time = (addDateTime(nows, 100));
//            Timer timer = new Timer();
//            timer.schedule(new RemindTask(), time);
//        }

    }

    @Override
    public void useCard(MpClientRaiseRecord mpClientRaiseRecord, MpClient client) {
        MpClientCard mpClientCard = new MpClientCard();
        mpClientCard.setCardId(mpClientRaiseRecord.getCardId());
        mpClientCard.setClientId(client.getClientId());
        List<MpClientCard> list =mpClientCardMapper.selectMpClientCardList(mpClientCard);
        if(list.size()<=0){
            throw new ServiceException("没有该道具卡");
        }
        MpClientCard mpClientCard1 = list.get(0);
        if(mpClientCard1.getCardCount()<=0){
            throw new ServiceException("道具卡数量不足");
        }
        MpClientRaiseRecord old = new MpClientRaiseRecord();
        old.setClientId(client.getClientId());
        old.setRaiseId(mpClientRaiseRecord.getRaiseId());
        List<MpClientRaiseRecord> oldList = mpClientRaiseRecordMapper.selectMpClientRaiseRecordList(old);
        if(oldList.size()<=0){
            throw new ServiceException("未参与游戏,不能使用道具卡");
        }
        List<MpClientRaiseRecord> isUseCard = oldList.stream().filter(e->e.getCardId()!=null&&e.getCardId()!=0).collect(Collectors.toList());
        if(isUseCard!=null&&isUseCard.size()>0){
            throw new ServiceException("不能重复使用道具卡");
        }
        MpClientRaiseRecord now = oldList.get(0);
        now.setCardId(mpClientRaiseRecord.getCardId());
        mpClientRaiseRecordMapper.updateMpClientRaiseRecord(now);
        mpClientCard1.setCardCount(mpClientCard1.getCardCount()-1);
        mpClientCardMapper.updateMpClientCard(mpClientCard1);

    }

    @Override
    public BigDecimal getFirstSilver(BigDecimal totalAmount) {
        List<PcRaiseSystemConfig> configs = pcRaiseSystemConfigMapper.selectPcRaiseSystemConfigList(new PcRaiseSystemConfig());
        BigDecimal rate = configs.get(0).getFirstOrderSilverRate();
        return rate.multiply(totalAmount).setScale( 2, BigDecimal.ROUND_HALF_UP );
    }

    @Override
    public Integer isTakeRaise(MpClientRaiseRecord mpClientRaiseRecord) {
        List<MpClientRaiseRecord> list = mpClientRaiseRecordMapper.selectMpClientRaiseRecordList(mpClientRaiseRecord);
        if(list.size()!=0){
           return 1;
        }
        return 2;
    }


}
